home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / WaveTableList.c < prev    next >
Text File  |  1994-12-03  |  28KB  |  908 lines

  1. /* WaveTableList.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "WaveTableList.h"
  31. #include "StringList.h"
  32. #include "Array.h"
  33. #include "Memory.h"
  34. #include "Alert.h"
  35. #include "DataMunging.h"
  36. #include "PcodeSystem.h"
  37. #include "WaveTableObject.h"
  38. #include "BufferedFileInput.h"
  39. #include "BufferedFileOutput.h"
  40. #include "Files.h"
  41. #include "Scrap.h"
  42.  
  43. struct WaveTableListRec
  44.     {
  45.         StringListRec*                    List;
  46.         struct CodeCenterRec*        CodeCenter;
  47.         struct MainWindowRec*        MainWindow;
  48.         ArrayRec*                                WaveTableArray;
  49.         MyBoolean                                WaveTableListChanged;
  50.     };
  51.  
  52.  
  53. #define MAGICSCRAPSTRING ("\xff\x00\x1f\xfe WaveTableObjectScrap")
  54.  
  55.  
  56. /* create a new wave table list */
  57. WaveTableListRec*        NewWaveTableList(struct MainWindowRec* MainWindow,
  58.                                             struct CodeCenterRec* CodeCenter, WinType* ScreenID,
  59.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  60.     {
  61.         WaveTableListRec*    WaveTableList;
  62.  
  63.         WaveTableList = (WaveTableListRec*)AllocPtrCanFail(sizeof(WaveTableListRec),
  64.             "WaveTableListRec");
  65.         if (WaveTableList == NIL)
  66.             {
  67.              FailurePoint1:
  68.                 return NIL;
  69.             }
  70.         WaveTableList->List = NewStringList(ScreenID,XLoc,YLoc,Width,Height,
  71.             GetScreenFont(),9,StringListDontAllowMultipleSelection,"Wave Tables");
  72.         if (WaveTableList->List == NIL)
  73.             {
  74.              FailurePoint2:
  75.                 ReleasePtr((char*)WaveTableList);
  76.                 goto FailurePoint1;
  77.             }
  78.         WaveTableList->WaveTableArray = NewArray();
  79.         if (WaveTableList->WaveTableArray == NIL)
  80.             {
  81.              FailurePoint3:
  82.                 DisposeStringList(WaveTableList->List);
  83.                 goto FailurePoint2;
  84.             }
  85.         WaveTableList->CodeCenter = CodeCenter;
  86.         WaveTableList->MainWindow = MainWindow;
  87.         WaveTableList->WaveTableListChanged = False;
  88.         return WaveTableList;
  89.     }
  90.  
  91.  
  92. /* delete the wave table list and all of the wave tables it contains */
  93. void                                DisposeWaveTableList(WaveTableListRec* WaveTableList)
  94.     {
  95.         long                            Scan;
  96.         long                            Limit;
  97.  
  98.         CheckPtrExistence(WaveTableList);
  99.         Limit = ArrayGetLength(WaveTableList->WaveTableArray);
  100.         for (Scan = 0; Scan < Limit; Scan += 1)
  101.             {
  102.                 WaveTableObjectRec*    WaveTableTemp;
  103.  
  104.                 WaveTableTemp = (WaveTableObjectRec*)ArrayGetElement(
  105.                     WaveTableList->WaveTableArray,Scan);
  106.                 DisposeWaveTableObject(WaveTableTemp);
  107.             }
  108.         DisposeArray(WaveTableList->WaveTableArray);
  109.         DisposeStringList(WaveTableList->List);
  110.         ReleasePtr((char*)WaveTableList);
  111.     }
  112.  
  113.  
  114. /* change the location of the wave table list in the window */
  115. void                                SetWaveTableListLocation(WaveTableListRec* WaveTableList,
  116.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  117.     {
  118.         CheckPtrExistence(WaveTableList);
  119.         SetStringListLoc(WaveTableList->List,XLoc,YLoc,Width,Height);
  120.     }
  121.  
  122.  
  123. /* redraw the wave table list */
  124. void                                WaveTableListRedraw(WaveTableListRec* WaveTableList)
  125.     {
  126.         CheckPtrExistence(WaveTableList);
  127.         RedrawStringList(WaveTableList->List);
  128.     }
  129.  
  130.  
  131. /* see if the specified coordinates falls inside the wave table list rectangle */
  132. MyBoolean                        WaveTableListHitTest(WaveTableListRec* WaveTableList,
  133.                                             OrdType XLoc, OrdType YLoc)
  134.     {
  135.         CheckPtrExistence(WaveTableList);
  136.         return StringListHitTest(WaveTableList->List,XLoc,YLoc);
  137.     }
  138.  
  139.  
  140. /* handle a mouse down event for the wave table list */
  141. void                                WaveTableListDoMouseDown(WaveTableListRec* WaveTableList,
  142.                                             OrdType XLoc, OrdType YLoc, ModifierFlags Modifiers)
  143.     {
  144.         CheckPtrExistence(WaveTableList);
  145.         if (StringListMouseDown(WaveTableList->List,XLoc,YLoc,Modifiers))
  146.             {
  147.                 /* if it returns true, then it was a double click */
  148.                 WaveTableListOpenSelection(WaveTableList);
  149.             }
  150.     }
  151.  
  152.  
  153. /* called when the window becomes active */
  154. void                                WaveTableListBecomeActive(WaveTableListRec* WaveTableList)
  155.     {
  156.         CheckPtrExistence(WaveTableList);
  157.         EnableStringList(WaveTableList->List);
  158.     }
  159.  
  160.  
  161. /* called when the window becomes inactive */
  162. void                                WaveTableListBecomeInactive(WaveTableListRec* WaveTableList)
  163.     {
  164.         CheckPtrExistence(WaveTableList);
  165.         DisableStringList(WaveTableList->List);
  166.     }
  167.  
  168.  
  169. /* called when a selection is made in another list, so that this list */
  170. /* is deselected */
  171. void                                WaveTableListDeselect(WaveTableListRec* WaveTableList)
  172.     {
  173.         CheckPtrExistence(WaveTableList);
  174.         DeselectAllStringListElements(WaveTableList->List);
  175.     }
  176.  
  177.  
  178. /* check to see if there is a selection in this list */
  179. MyBoolean                        WaveTableListIsThereSelection(WaveTableListRec* WaveTableList)
  180.     {
  181.         CheckPtrExistence(WaveTableList);
  182.         return (GetStringListHowManySelectedItems(WaveTableList->List) > 0);
  183.     }
  184.  
  185.  
  186. /* check to see if any of the wave tables contained in this list need to be saved */
  187. MyBoolean                        DoesWaveTableListNeedToBeSaved(WaveTableListRec* WaveTableList)
  188.     {
  189.         long                            Scan;
  190.         long                            Limit;
  191.         MyBoolean                    Flag;
  192.  
  193.         CheckPtrExistence(WaveTableList);
  194.         Flag = WaveTableList->WaveTableListChanged;
  195.         Limit = ArrayGetLength(WaveTableList->WaveTableArray);
  196.         for (Scan = 0; (Scan < Limit) && !Flag; Scan += 1)
  197.             {
  198.                 WaveTableObjectRec*    WaveTableTemp;
  199.  
  200.                 WaveTableTemp = (WaveTableObjectRec*)ArrayGetElement(
  201.                     WaveTableList->WaveTableArray,Scan);
  202.                 if (HasWaveTableObjectBeenModified(WaveTableTemp))
  203.                     {
  204.                         Flag = True;
  205.                     }
  206.             }
  207.         return Flag;
  208.     }
  209.  
  210.  
  211. /* open an edit window for the selected wave table */
  212. void                                WaveTableListOpenSelection(WaveTableListRec* WaveTableList)
  213.     {
  214.         ArrayRec*                    ListOfSelections;
  215.  
  216.         CheckPtrExistence(WaveTableList);
  217.         ListOfSelections = GetListOfSelectedItems(WaveTableList->List);
  218.         if (ListOfSelections != NIL)
  219.             {
  220.                 long                            Scan;
  221.                 long                            Limit;
  222.  
  223.                 Limit = ArrayGetLength(ListOfSelections);
  224.                 for (Scan = 0; Scan < Limit; Scan += 1)
  225.                     {
  226.                         WaveTableObjectRec*        WaveTableTemp;
  227.  
  228.                         WaveTableTemp = (WaveTableObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  229.                         WaveTableObjectOpenWindow(WaveTableTemp);
  230.                     }
  231.                 DisposeArray(ListOfSelections);
  232.             }
  233.     }
  234.  
  235.  
  236. /* create a new wave table and open a window for it */
  237. void                                WaveTableListNewWaveTable(WaveTableListRec* WaveTableList)
  238.     {
  239.         WaveTableObjectRec*    WaveTable;
  240.  
  241.         CheckPtrExistence(WaveTableList);
  242.         /* create the object */
  243.         WaveTable = NewWaveTableObject(WaveTableList->CodeCenter,
  244.             WaveTableList->MainWindow,WaveTableList);
  245.         if (WaveTable == NIL)
  246.             {
  247.              FailurePoint1:
  248.                 AlertHalt("There is not enough memory available to "
  249.                     "create a new wave table.",NIL);
  250.                 return;
  251.             }
  252.         /* add it to the string list */
  253.         if (!InsertStringListElement(WaveTableList->List,NIL,NIL,WaveTable,True))
  254.             {
  255.              FailurePoint2:
  256.                 DisposeWaveTableObject(WaveTable);
  257.                 goto FailurePoint1;
  258.             }
  259.         MainWindowDeselectAllOtherStringLists(WaveTableList->MainWindow,WaveTableList);
  260.         SelectStringListElement(WaveTableList->List,WaveTable);
  261.         MakeStringListSelectionVisible(WaveTableList->List);
  262.         /* add it to the array */
  263.         if (!ArrayAppendElement(WaveTableList->WaveTableArray,WaveTable))
  264.             {
  265.              FailurePoint3:
  266.                 RemoveStringListElement(WaveTableList->List,WaveTable,True);
  267.                 goto FailurePoint2;
  268.             }
  269.         /* update our internal flags */
  270.         WaveTableList->WaveTableListChanged = True;
  271.         /* change the name in the list */
  272.         WaveTableListWaveTableNameChanged(WaveTableList,WaveTable);
  273.         /* show the window */
  274.         WaveTableObjectOpenWindow(WaveTable);
  275.     }
  276.  
  277.  
  278. /* delete the selected wave table */
  279. void                                WaveTableListDeleteSelection(WaveTableListRec* WaveTableList)
  280.     {
  281.         ArrayRec*                    ListOfSelections;
  282.  
  283.         CheckPtrExistence(WaveTableList);
  284.         ListOfSelections = GetListOfSelectedItems(WaveTableList->List);
  285.         if (ListOfSelections != NIL)
  286.             {
  287.                 long                                Scan;
  288.                 long                                Limit;
  289.  
  290.                 Limit = ArrayGetLength(ListOfSelections);
  291.                 for (Scan = 0; Scan < Limit; Scan += 1)
  292.                     {
  293.                         WaveTableObjectRec*    OneToZap;
  294.  
  295.                         OneToZap = (WaveTableObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  296.                         WaveTableListDeleteWaveTable(WaveTableList,OneToZap);
  297.                     }
  298.                 DisposeArray(ListOfSelections);
  299.             }
  300.     }
  301.  
  302.  
  303. /* delete the explicitly specified wave table */
  304. void                                WaveTableListDeleteWaveTable(WaveTableListRec* WaveTableList,
  305.                                             struct WaveTableObjectRec* TheWaveTable)
  306.     {
  307.         long                                Scan;
  308.         long                                Limit;
  309.  
  310.         CheckPtrExistence(WaveTableList);
  311.         MainWindowClearInstrObjects(WaveTableList->MainWindow);
  312.         Limit = ArrayGetLength(WaveTableList->WaveTableArray);
  313.         for (Scan = 0; Scan < Limit; Scan += 1)
  314.             {
  315.                 WaveTableObjectRec*        WaveTableTemp;
  316.  
  317.                 WaveTableTemp = (WaveTableObjectRec*)ArrayGetElement(
  318.                     WaveTableList->WaveTableArray,Scan);
  319.                 if (TheWaveTable == WaveTableTemp)
  320.                     {
  321.                         FileSpec*                    BackupFileWhere;
  322.                         FileType*                    BackupFile;
  323.                         MyBoolean                    Success = False;
  324.  
  325.                         BackupFileWhere = NewTempFileSpec(CODE4BYTES('?','?','?','?'),
  326.                             CODE4BYTES('?','?','?','?'));
  327.                         if (BackupFileWhere != NIL)
  328.                             {
  329.                                 if (OpenFile(BackupFileWhere,&BackupFile,eReadAndWrite))
  330.                                     {
  331.                                         BufferedOutputRec*    Output;
  332.  
  333.                                         Output = NewBufferedOutput(BackupFile);
  334.                                         if (Output != NIL)
  335.                                             {
  336.                                                 if (WriteBufferedOutput(Output,sizeof(MAGICSCRAPSTRING),
  337.                                                     MAGICSCRAPSTRING))
  338.                                                     {
  339.                                                         if (WaveTableObjectWriteDataOut(TheWaveTable,Output)
  340.                                                             == eFileLoadNoError)
  341.                                                             {
  342.                                                                 Success = True;
  343.                                                             }
  344.                                                     }
  345.                                                 if (!EndBufferedOutput(Output))
  346.                                                     {
  347.                                                         Success = False;
  348.                                                     }
  349.                                             }
  350.                                          else
  351.                                             {
  352.                                                 CloseFile(BackupFile);
  353.                                             }
  354.                                     }
  355.                                  else
  356.                                     {
  357.                                         DeleteFile(BackupFileWhere);
  358.                                         DisposeFileSpec(BackupFileWhere);
  359.                                     }
  360.                             }
  361.                         if (Success)
  362.                             {
  363.                                 MainWindowNewDeleteUndoInfo(WaveTableList->MainWindow,BackupFileWhere,
  364.                                     BackupFile);
  365.                                 DisposeWaveTableObject(WaveTableTemp);
  366.                                 RemoveStringListElement(WaveTableList->List,WaveTableTemp,True);
  367.                                 ArrayDeleteElement(WaveTableList->WaveTableArray,Scan);
  368.                                 WaveTableList->WaveTableListChanged = True;
  369.                             }
  370.                          else
  371.                             {
  372.                                 YesNoCancelType        Decision;
  373.  
  374.                                 Decision = AskYesNoCancel("Unable to save undo information for object.  "
  375.                                     "Delete object anyway?",NIL,"Delete","Cancel",NIL/*nothirdbutton*/);
  376.                                 if (Decision == eYes)
  377.                                     {
  378.                                         DisposeWaveTableObject(WaveTableTemp);
  379.                                         RemoveStringListElement(WaveTableList->List,WaveTableTemp,True);
  380.                                         ArrayDeleteElement(WaveTableList->WaveTableArray,Scan);
  381.                                         WaveTableList->WaveTableListChanged = True;
  382.                                     }
  383.                             }
  384.                         return;
  385.                     }
  386.             }
  387.         EXECUTE(PRERR(AllowResume,"WaveTableListDeleteWaveTable:  couldn't find object"));
  388.     }
  389.  
  390.  
  391. /* the name of a wave table has changed, so the name in the scrolling */
  392. /* list must also be changed */
  393. void                                WaveTableListWaveTableNameChanged(WaveTableListRec* WaveTableList,
  394.                                             struct WaveTableObjectRec* TheWaveTable)
  395.     {
  396.         char*                            WaveTableName;
  397.  
  398.         CheckPtrExistence(WaveTableList);
  399.         CheckPtrExistence(TheWaveTable);
  400.         ERROR(ArrayFindElement(WaveTableList->WaveTableArray,TheWaveTable) < 0,
  401.             PRERR(ForceAbort,"WaveTableListWaveTableNameChanged:  unknown wave table"));
  402.         WaveTableName = WaveTableObjectGetNameCopy(TheWaveTable);
  403.         if (WaveTableName != NIL)
  404.             {
  405.                 char*                            WaveTableNameNullTerminated;
  406.  
  407.                 WaveTableNameNullTerminated = BlockToStringCopy(WaveTableName);
  408.                 if (WaveTableNameNullTerminated != NIL)
  409.                     {
  410.                         ChangeStringListElementName(WaveTableList->List,
  411.                             WaveTableNameNullTerminated,TheWaveTable);
  412.                         ReleasePtr(WaveTableNameNullTerminated);
  413.                     }
  414.                 ReleasePtr(WaveTableName);
  415.             }
  416.     }
  417.  
  418.  
  419. /* look for a specified wave table.  returns NIL if not found.  the name is NOT null */
  420. /* terminated */
  421. struct WaveTableObjectRec*    WaveTableListLookupNamedWaveTable(
  422.                                             WaveTableListRec* WaveTableList, char* Name)
  423.     {
  424.         long                            Scan;
  425.         long                            Limit;
  426.  
  427.         CheckPtrExistence(WaveTableList);
  428.         CheckPtrExistence(Name);
  429.         Limit = ArrayGetLength(WaveTableList->WaveTableArray);
  430.         for (Scan = 0; Scan < Limit; Scan += 1)
  431.             {
  432.                 WaveTableObjectRec*        WaveTable;
  433.                 char*                                    NameCopy;
  434.  
  435.                 WaveTable = (WaveTableObjectRec*)ArrayGetElement(
  436.                     WaveTableList->WaveTableArray,Scan);
  437.                 NameCopy = WaveTableObjectGetNameCopy(WaveTable);
  438.                 if (NameCopy != NIL)
  439.                     {
  440.                         if (PtrSize(Name) == PtrSize(NameCopy))
  441.                             {
  442.                                 if (MemEqu(Name,NameCopy,PtrSize(Name)))
  443.                                     {
  444.                                         ReleasePtr(NameCopy);
  445.                                         return WaveTable;
  446.                                     }
  447.                             }
  448.                         ReleasePtr(NameCopy);
  449.                     }
  450.             }
  451.         return NIL;
  452.     }
  453.  
  454.  
  455. /* the document's name changed, so the windows need to be updated */
  456. void                                WaveTableListGlobalNameChange(WaveTableListRec* WaveTableList,
  457.                                             char* NewFilename)
  458.     {
  459.         long                            Scan;
  460.         long                            Limit;
  461.  
  462.         CheckPtrExistence(WaveTableList);
  463.         Limit = ArrayGetLength(WaveTableList->WaveTableArray);
  464.         for (Scan = 0; Scan < Limit; Scan += 1)
  465.             {
  466.                 WaveTableObjectRec*        WaveTable;
  467.  
  468.                 WaveTable = (WaveTableObjectRec*)ArrayGetElement(
  469.                     WaveTableList->WaveTableArray,Scan);
  470.                 WaveTableObjectGlobalNameChange(WaveTable,NewFilename);
  471.             }
  472.     }
  473.  
  474.  
  475. /* use the provided data to open a new wave table with the specified attributes. */
  476. /* this is used when opening an algorithmic wave table as a data wave table. */
  477. /* RawData MUST be valid. */
  478. WaveTableObjectRec*    WaveTableListCopyRawWaveTableAndOpen(WaveTableListRec* WaveTableList,
  479.                                             char* RawData, NumBitsType NumBits, long NumTables,
  480.                                             long FramesPerTable)
  481.     {
  482.         WaveTableObjectRec*    WaveTable;
  483.  
  484.         CheckPtrExistence(WaveTableList);
  485.         CheckPtrExistence(RawData);
  486.         /* create the object */
  487.         WaveTable = NewWaveTableObjectFromData(WaveTableList->CodeCenter,
  488.             WaveTableList->MainWindow,WaveTableList,RawData,NumBits,NumTables,FramesPerTable);
  489.         if (WaveTable == NIL)
  490.             {
  491.              FailurePoint1:
  492.                 AlertHalt("There is not enough memory available to create a new wave table.",NIL);
  493.                 return NIL;
  494.             }
  495.         /* add it to the string list */
  496.         if (!InsertStringListElement(WaveTableList->List,NIL,NIL,WaveTable,True))
  497.             {
  498.              FailurePoint2:
  499.                 DisposeWaveTableObject(WaveTable);
  500.                 goto FailurePoint1;
  501.             }
  502.         MainWindowDeselectAllOtherStringLists(WaveTableList->MainWindow,WaveTableList);
  503.         SelectStringListElement(WaveTableList->List,WaveTable);
  504.         MakeStringListSelectionVisible(WaveTableList->List);
  505.         /* add it to the array */
  506.         if (!ArrayAppendElement(WaveTableList->WaveTableArray,WaveTable))
  507.             {
  508.              FailurePoint3:
  509.                 RemoveStringListElement(WaveTableList->List,WaveTable,True);
  510.                 goto FailurePoint2;
  511.             }
  512.         /* update our internal flags */
  513.         WaveTableList->WaveTableListChanged = True;
  514.         /* change the name in the list */
  515.         WaveTableListWaveTableNameChanged(WaveTableList,WaveTable);
  516.         /* show the window */
  517.         WaveTableObjectOpenWindow(WaveTable);
  518.         return WaveTable;
  519.     }
  520.  
  521.  
  522. /* get the frame count for the named wave table */
  523. SampleErrors                WaveTableListGetWaveTableFrameCount(WaveTableListRec* WaveTableList,
  524.                                             char* WaveName, long* FrameCountOut)
  525.     {
  526.         WaveTableObjectRec*    WaveTable;
  527.  
  528.         CheckPtrExistence(WaveTableList);
  529.         ERROR(FrameCountOut == NIL,PRERR(ForceAbort,
  530.             "WaveTableListGetWaveTableFrameCount:  frame count out is NIL"));
  531.         WaveTable = WaveTableListLookupNamedWaveTable(WaveTableList,WaveName);
  532.         if (WaveTable == NIL)
  533.             {
  534.                 return eEvalSampleUndefined;
  535.             }
  536.         *FrameCountOut = WaveTableObjectEntriesPerTable(WaveTable);
  537.         return eEvalSampleNoError;
  538.     }
  539.  
  540.  
  541. /* get the table count for the named wave table */
  542. SampleErrors                WaveTableListGetWaveTableTableCount(WaveTableListRec* WaveTableList,
  543.                                             char* WaveName, long* TableCountOut)
  544.     {
  545.         WaveTableObjectRec*    WaveTable;
  546.  
  547.         CheckPtrExistence(WaveTableList);
  548.         ERROR(TableCountOut == NIL,PRERR(ForceAbort,
  549.             "WaveTableListGetWaveTableTableCount:  table count out is NIL"));
  550.         WaveTable = WaveTableListLookupNamedWaveTable(WaveTableList,WaveName);
  551.         if (WaveTable == NIL)
  552.             {
  553.                 return eEvalSampleUndefined;
  554.             }
  555.         *TableCountOut = WaveTableObjectGetNumTables(WaveTable);
  556.         return eEvalSampleNoError;
  557.     }
  558.  
  559.  
  560. /* get the table array for the named wave table */
  561. SampleErrors                WaveTableListGetWaveTableArray(WaveTableListRec* WaveTableList,
  562.                                             char* WaveName, largefixedsigned** TableOut)
  563.     {
  564.         WaveTableObjectRec*    WaveTable;
  565.  
  566.         CheckPtrExistence(WaveTableList);
  567.         ERROR(TableOut == NIL,PRERR(ForceAbort,
  568.             "WaveTableListGetWaveTableArray:  table out is NIL"));
  569.         WaveTable = WaveTableListLookupNamedWaveTable(WaveTableList,WaveName);
  570.         if (WaveTable == NIL)
  571.             {
  572.                 return eEvalSampleUndefined;
  573.             }
  574.         *TableOut = WaveTableObjectGetFixed(WaveTable);
  575.         return eEvalSampleNoError;
  576.     }
  577.  
  578.  
  579. /*   4-byte little endian number of wave table objects (positive 2's complement) */
  580. /*   n-bytes data for the wave table objects */
  581.  
  582.  
  583. /* read wave table objects from a file.  returns True if completely successful. */
  584. FileLoadingErrors        WaveTableListReadData(WaveTableListRec* WaveTableList,
  585.                                             struct BufferedInputRec* Input)
  586.     {
  587.         signed long                ObjectCount;
  588.         long                            Scan;
  589.  
  590.         CheckPtrExistence(WaveTableList);
  591.         CheckPtrExistence(Input);
  592.  
  593.         /*   4-byte little endian number of objects (positive 2's complement) */
  594.         if (!ReadBufferedSignedLongLittleEndian(Input,&ObjectCount))
  595.             {
  596.                 return eFileLoadDiskError;
  597.             }
  598.         if (ObjectCount < 0)
  599.             {
  600.                 return eFileLoadBadFormat;
  601.             }
  602.  
  603.         /* load the objects */
  604.         for (Scan = 0; Scan < ObjectCount; Scan += 1)
  605.             {
  606.                 WaveTableObjectRec*    WaveTableTemp EXECUTE(= (WaveTableObjectRec*)0x81818181);
  607.                 FileLoadingErrors        Error;
  608.  
  609.                 /* load the object */
  610.                 Error = WaveTableObjectNewFromFile(&WaveTableTemp,Input,
  611.                     WaveTableList->CodeCenter,WaveTableList->MainWindow,WaveTableList);
  612.                 if (Error != eFileLoadNoError)
  613.                     {
  614.                      FailurePoint1:
  615.                         return Error;
  616.                     }
  617.                 /* add it to the string list */
  618.                 if (!InsertStringListElement(WaveTableList->List,NIL,NIL,WaveTableTemp,True))
  619.                     {
  620.                      FailurePoint2:
  621.                         DisposeWaveTableObject(WaveTableTemp);
  622.                         Error = eFileLoadOutOfMemory;
  623.                         goto FailurePoint1;
  624.                     }
  625.                 /* add it to the array */
  626.                 if (!ArrayAppendElement(WaveTableList->WaveTableArray,WaveTableTemp))
  627.                     {
  628.                      FailurePoint3:
  629.                         RemoveStringListElement(WaveTableList->List,WaveTableTemp,True);
  630.                         goto FailurePoint2;
  631.                     }
  632.                 /* change the name in the list */
  633.                 WaveTableListWaveTableNameChanged(WaveTableList,WaveTableTemp);
  634.             }
  635.  
  636.         return eFileLoadNoError;
  637.     }
  638.  
  639.  
  640. /* write wave table objects to a file.  returns True if completely successful. */
  641. FileLoadingErrors        WaveTableListWriteData(WaveTableListRec* WaveTableList,
  642.                                             struct BufferedOutputRec* Output)
  643.     {
  644.         long                            NumberOfObjects;
  645.         long                            Scan;
  646.  
  647.         CheckPtrExistence(Output);
  648.         CheckPtrExistence(WaveTableList);
  649.  
  650.         /*   4-byte little endian number of objects (positive 2's complement) */
  651.         NumberOfObjects = ArrayGetLength(WaveTableList->WaveTableArray);
  652.         if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfObjects))
  653.             {
  654.                 return eFileLoadDiskError;
  655.             }
  656.  
  657.         /* write out the objects */
  658.         for (Scan = 0; Scan < NumberOfObjects; Scan += 1)
  659.             {
  660.                 WaveTableObjectRec*        WaveTable;
  661.                 FileLoadingErrors            Error;
  662.  
  663.                 /* get the object */
  664.                 WaveTable = (WaveTableObjectRec*)ArrayGetElement(
  665.                     WaveTableList->WaveTableArray,Scan);
  666.                 /* write it out */
  667.                 Error = WaveTableObjectWriteDataOut(WaveTable,Output);
  668.                 /* handle errors */
  669.                 if (Error != eFileLoadNoError)
  670.                     {
  671.                         return Error;
  672.                     }
  673.             }
  674.  
  675.         return eFileLoadNoError;
  676.     }
  677.  
  678.  
  679. /* after a file has been saved, this is called to mark all objects as not modified. */
  680. void                                WaveTableListMarkAllObjectsSaved(WaveTableListRec* WaveTableList)
  681.     {
  682.         long                            Scan;
  683.         long                            Limit;
  684.  
  685.         CheckPtrExistence(WaveTableList);
  686.         Limit = ArrayGetLength(WaveTableList->WaveTableArray);
  687.         for (Scan = 0; Scan < Limit; Scan += 1)
  688.             {
  689.                 WaveTableObjectRec*        WaveTable;
  690.  
  691.                 WaveTable = (WaveTableObjectRec*)ArrayGetElement(
  692.                     WaveTableList->WaveTableArray,Scan);
  693.                 WaveTableObjectMarkAsSaved(WaveTable);
  694.             }
  695.         WaveTableList->WaveTableListChanged = False;
  696.     }
  697.  
  698.  
  699. /* copy the selected object in the list to the clipboard.  return False if failed. */
  700. MyBoolean                        WaveTableListCopyObject(WaveTableListRec* WaveTableList)
  701.     {
  702.         ArrayRec*                            ListOfSelections;
  703.         MyBoolean                            TotalSuccessFlag = False;
  704.  
  705.         CheckPtrExistence(WaveTableList);
  706.         ListOfSelections = GetListOfSelectedItems(WaveTableList->List);
  707.         if (ListOfSelections != NIL)
  708.             {
  709.                 if (ArrayGetLength(ListOfSelections) >= 1)
  710.                     {
  711.                         WaveTableObjectRec*    WaveTableTemp;
  712.                         FileSpec*                        TempFileLocation;
  713.  
  714.                         WaveTableTemp = (WaveTableObjectRec*)ArrayGetElement(ListOfSelections,0);
  715.                         /* open the temporary file */
  716.                         TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  717.                             CODE4BYTES('\?','\?','\?','\?'));
  718.                         if (TempFileLocation != NIL)
  719.                             {
  720.                                 FileType*                            FileDescriptor;
  721.  
  722.                                 if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  723.                                     {
  724.                                         BufferedOutputRec*        BufferedFile;
  725.  
  726.                                         BufferedFile = NewBufferedOutput(FileDescriptor);
  727.                                         if (BufferedFile != NIL)
  728.                                             {
  729.                                                 MyBoolean                            WriteSucceeded = False;
  730.  
  731.                                                 if (WriteBufferedOutput(BufferedFile,sizeof(MAGICSCRAPSTRING),
  732.                                                     MAGICSCRAPSTRING))
  733.                                                     {
  734.                                                         if (WaveTableObjectWriteDataOut(WaveTableTemp,BufferedFile)
  735.                                                             == eFileLoadNoError)
  736.                                                             {
  737.                                                                 WriteSucceeded = True;
  738.                                                             }
  739.                                                     }
  740.                                                 if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  741.                                                     {
  742.                                                         char*                            Buffer;
  743.                                                         long                            NumberOfBytes;
  744.  
  745.                                                         NumberOfBytes = GetFileLength(FileDescriptor);
  746.                                                         Buffer = AllocPtrCanFail(NumberOfBytes,
  747.                                                             "WaveTableListCopyObject:  scrap buffer");
  748.                                                         if (Buffer != NIL)
  749.                                                             {
  750.                                                                 if (SetFilePosition(FileDescriptor,0))
  751.                                                                     {
  752.                                                                         if (0 == ReadFromFile(FileDescriptor,
  753.                                                                             Buffer,NumberOfBytes))
  754.                                                                             {
  755.                                                                                 if (SetScrapToThis(Buffer))
  756.                                                                                     {
  757.                                                                                         TotalSuccessFlag = True;
  758.                                                                                     }
  759.                                                                             }
  760.                                                                     }
  761.                                                                 ReleasePtr(Buffer);
  762.                                                             }
  763.                                                     }
  764.                                             }
  765.                                         CloseFile(FileDescriptor);
  766.                                     }
  767.                                 DeleteFile(TempFileLocation);
  768.                                 DisposeFileSpec(TempFileLocation);
  769.                             }
  770.                     }
  771.                 DisposeArray(ListOfSelections);
  772.             }
  773.         return TotalSuccessFlag;
  774.     }
  775.  
  776.  
  777. /* try to paste the clipboard in as a wave table object.  returns False if */
  778. /* it failed or the clipboard did not contain a wave table object. */
  779. MyBoolean                        WaveTableListPasteObject(WaveTableListRec* WaveTableList)
  780.     {
  781.         MyBoolean                    TotalSuccessFlag = False;
  782.         char*                            Scrap;
  783.  
  784.         CheckPtrExistence(WaveTableList);
  785.         Scrap = GetCopyOfScrap();
  786.         if (Scrap != NIL)
  787.             {
  788.                 FileSpec*                    TempFileLocation;
  789.  
  790.                 TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  791.                     CODE4BYTES('\?','\?','\?','\?'));
  792.                 if (TempFileLocation != NIL)
  793.                     {
  794.                         FileType*                            FileDescriptor;
  795.  
  796.                         if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  797.                             {
  798.                                 BufferedOutputRec*        BufferedFile;
  799.  
  800.                                 BufferedFile = NewBufferedOutput(FileDescriptor);
  801.                                 if (BufferedFile != NIL)
  802.                                     {
  803.                                         MyBoolean                            WriteSucceeded = False;
  804.  
  805.                                         if (WriteBufferedOutput(BufferedFile,PtrSize(Scrap),Scrap))
  806.                                             {
  807.                                                 WriteSucceeded = True;
  808.                                             }
  809.                                         if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  810.                                             {
  811.                                                 TotalSuccessFlag = WaveTableListPasteFromFile(
  812.                                                     WaveTableList,FileDescriptor);
  813.                                             }
  814.                                     }
  815.                                 CloseFile(FileDescriptor);
  816.                             }
  817.                         DeleteFile(TempFileLocation);
  818.                         DisposeFileSpec(TempFileLocation);
  819.                     }
  820.                 ReleasePtr(Scrap);
  821.             }
  822.         return TotalSuccessFlag;
  823.     }
  824.  
  825.  
  826. /* try to paste the wave table object in from the file */
  827. MyBoolean                        WaveTableListPasteFromFile(WaveTableListRec* WaveTableList,
  828.                                             struct FileType* File)
  829.     {
  830.         MyBoolean                    TotalSuccessFlag = False;
  831.  
  832.         CheckPtrExistence(WaveTableList);
  833.         if (SetFilePosition(File,0))
  834.             {
  835.                 BufferedInputRec*    InputFile;
  836.  
  837.                 InputFile = NewBufferedInput(File);
  838.                 if (InputFile != NIL)
  839.                     {
  840.                         char                            HeaderTest[sizeof(MAGICSCRAPSTRING)];
  841.  
  842.                         if (ReadBufferedInput(InputFile,sizeof(MAGICSCRAPSTRING),HeaderTest))
  843.                             {
  844.                                 if (MemEqu(MAGICSCRAPSTRING,HeaderTest,sizeof(MAGICSCRAPSTRING)))
  845.                                     {
  846.                                         WaveTableObjectRec*        WaveTableTemp EXECUTE(= (WaveTableObjectRec*)0x81818181);
  847.  
  848.                                         if (eFileLoadNoError == WaveTableObjectNewFromFile(&WaveTableTemp,InputFile,
  849.                                             WaveTableList->CodeCenter,WaveTableList->MainWindow,WaveTableList))
  850.                                             {
  851.                                                 CheckPtrExistence(WaveTableTemp);
  852.                                                 /* add it to the scrolling object list */
  853.                                                 if (!InsertStringListElement(WaveTableList->List,NIL,NIL,WaveTableTemp,True))
  854.                                                     {
  855.                                                      FailurePoint:
  856.                                                         DisposeWaveTableObject(WaveTableTemp);
  857.                                                     }
  858.                                                  else
  859.                                                     {
  860.                                                         MainWindowDeselectAllOtherStringLists(WaveTableList->MainWindow,WaveTableList);
  861.                                                         SelectStringListElement(WaveTableList->List,WaveTableTemp);
  862.                                                         MakeStringListSelectionVisible(WaveTableList->List);
  863.                                                         /* add it to the array */
  864.                                                         if (!ArrayAppendElement(WaveTableList->WaveTableArray,WaveTableTemp))
  865.                                                             {
  866.                                                                 RemoveStringListElement(WaveTableList->List,WaveTableTemp,True);
  867.                                                                 goto FailurePoint;
  868.                                                             }
  869.                                                          else
  870.                                                             {
  871.                                                                 /* change the name in the list */
  872.                                                                 WaveTableListWaveTableNameChanged(WaveTableList,WaveTableTemp);
  873.                                                                 TotalSuccessFlag = True;
  874.                                                                 WaveTableList->WaveTableListChanged = True;
  875.                                                             }
  876.                                                     }
  877.                                             }
  878.                                     }
  879.                             }
  880.                         EndBufferedInput(InputFile);
  881.                     }
  882.             }
  883.         return TotalSuccessFlag;
  884.     }
  885.  
  886.  
  887. /* find out how many wave tables there are in this list */
  888. long                                WaveTableListHowMany(WaveTableListRec* WaveTableList)
  889.     {
  890.         CheckPtrExistence(WaveTableList);
  891.         return ArrayGetLength(WaveTableList->WaveTableArray);
  892.     }
  893.  
  894.  
  895. /* get an indexed wave tables from the list */
  896. struct WaveTableObjectRec*    WaveTableListGetIndexedWaveTable(
  897.                                             WaveTableListRec* WaveTableList, long Index)
  898.     {
  899.         WaveTableObjectRec*    WaveTable;
  900.  
  901.         CheckPtrExistence(WaveTableList);
  902.         ERROR((Index < 0) || (Index >= WaveTableListHowMany(WaveTableList)),PRERR(ForceAbort,
  903.             "WaveTableListGetIndexedWaveTable:  index out of range"));
  904.         WaveTable = (WaveTableObjectRec*)ArrayGetElement(WaveTableList->WaveTableArray,Index);
  905.         CheckPtrExistence(WaveTable);
  906.         return WaveTable;
  907.     }
  908.